/**
 * Poll functionality for SolFray
 * Handles lazy-loading poll data, voting, and hidden results UX
 */

let POLLING_SERVER_URL;

function initPolls(server_url = '') {
    POLLING_SERVER_URL = typeof server_url === 'string' ? server_url : ''; // empty str for rel path
    const jwt = localStorage.getItem('jwt');
    if (!jwt) {
        $('.poll-loading').add('.poll-container').each(function() {
            $(this).removeClass('poll-container').addClass('poll-loading').empty().append('<small class="text-muted"><span class="bi bi-filter-left"></span> Login to see poll</small>');
        });
        return;
    }
    var pollChatIds = [];
    $('.poll-loading').each(function() {
        const $placeholder = $(this);
        const chatId = $placeholder.data('chat-id');
        pollChatIds.push(chatId);
    });
    // Make pollChatIds unique
    pollChatIds = [...new Set(pollChatIds)];
    if (pollChatIds.length < 1) {
        return;
    }
    pollChatIds = pollChatIds.join(',');
    headers = { 'Authorization': `Bearer ${jwt}` };
    $.ajax({
        url: `${server_url}/api/batched-polls?chat_ids=${pollChatIds}`,
        method: 'GET',
        headers: headers,
        success: function(response) {
            renderPolls(response?.poll_list);
        },
        error: function(xhr, status, error) {
            console.error('Failed to load poll data.', xhr, status, error);
        }
    });
}

function renderPolls(pollList) {
    if (!Array.isArray(pollList)) {
        console.error('Invalid poll data, expected array: ', pollList);
        return;
    }
    for (const pollData of pollList) {
        renderPoll(pollData);
    }
}

function renderPoll(pollData) {
    try {
        const isActive = pollData.status === 'active';
        const isClosed = pollData.status === 'closed';
        const userVoted = pollData?.my_vote || false;

        // IMPORTANT: Hide results until user votes (or poll is closed)
        const showResults = userVoted || isClosed;

        // Calculate percentages
        const total = pollData.total_votes || 0;
        const options = pollData.options.map(opt => {
            const percentage = total > 0 ? Math.round((opt.votes / total) * 100) : 0;
            const isVoted = opt.option_id === pollData.user_voted_option_id;
            return { ...opt, percentage, isVoted };
        });

        const threadContainers = $(`.thread[data-chat-id="${pollData.chat_id}"]`);
        if (threadContainers.length < 1) {
            throw new Error('Poll Error: Thread container not found');
        }

        // Build HTML using overlay-compact style
        const containerClass = `poll-container poll-style-overlay-compact poll-card-compact ${isActive ? 'poll-active' : ''} ${isClosed ? 'poll-closed' : ''} ${showResults ? 'poll-show-results' : 'poll-hide-results'}`;
        const container = $(`<div class="${containerClass}" data-poll-chat-id="${pollData.chat_id}" style="display:none;"></div>`);
        let optionsHtml = options.map(opt => {
            const clickable = isActive && !userVoted ? 'clickable' : '';
            const votedClass = opt.isVoted ? 'voted' : '';

            // Show results (bars, counts, percentages) only if user voted or poll closed
            if (showResults) {
                var votesStr = opt.votes > 1000 ? Math.round(opt.votes / 1000) + 'K' : opt.votes;
                return `
                    <div class="poll-option ${clickable} ${votedClass}" 
                         data-option-id="${opt.option_id}"
                         data-poll-id="${pollData.poll_id}" 
                         data-poll-chat-id="${pollData.chat_id}">
                        <div class="poll-option-bar-fill" style="width: ${opt.percentage}%"></div>
                        <div class="poll-option-overlay-content">
                            <span class="poll-option-text">${opt.text}${(opt.votes ? `&nbsp<span style="opacity:0.7;"><span class="bi bi-arrow-up-short"></span>${votesStr}</span>` : '')}</span>
                            <span class="poll-option-votes">${opt.percentage}%</span>
                        </div>
                    </div>
                `;
            } else {
                // Hide results - show only option text before voting (NO bars, counts, or percentages)
                return `
                    <div class="poll-option ${clickable}" 
                         data-option-id="${opt.option_id}"
                         data-poll-id="${pollData.poll_id}" 
                         data-poll-chat-id="${pollData.chat_id}">
                        <div class="poll-option-overlay-content">
                            <span class="poll-option-text">${opt.text}</span>
                        </div>
                    </div>
                `;
            }
        }).join('');

        // Status text
        let statusText = '';
        if (isClosed) {
            statusText = '• Poll closed';
        } else if (pollData.end_time) {
            statusText = '• Ends ' + new Date(pollData.end_time).toLocaleDateString();
        } else {
            statusText = isActive && !userVoted ? '• Click to vote!' : '• Active poll';
        }

        // Footer - hide vote count if results are hidden
        const footerHtml = showResults
            ? `<span class="poll-total-votes">${total} vote${(total == 1 ? '' : 's')}</span>`
            : `<span class="poll-total-votes">Vote to see results</span>`;

        // redundant question removed from first like of append string below.
        // Not needed as polls are always part of a thread which already has the question.
        // <div class="poll-question">${pollData.question}</div>
        container.append(`
            ${optionsHtml}
            <div class="poll-footer">
                ${footerHtml}
                <span class="poll-status">${statusText}</span>
            </div>
        `);
        threadContainers.each(function() {
            const targets = $(this).find('.poll-loading');
            if (targets.length > 0) {
                targets.last().after(container.clone());
                targets.remove();
            }
        });
        setTimeout(function() {
            $('.poll-container:not(.showing)').css({ display: 'block' }).addClass('showing');
        }, 100);
    } catch (e) {
        console.error('Error building poll HTML:', e, pollData);
    }
}

// Vote handling
$(document).ready(function() {
    // Delegate event handler for poll option clicks
    $(document).on('click', '.poll-active .poll-option.clickable', function() {
        const jwt = localStorage.getItem('jwt');
        if (!jwt) {
            alert('Please login to vote'); // Should never happen
        }
        const $option = $(this);
        // const pollId = $option.attr('poll-id'); // Server now expects chat_id instead
        const chatId = $option.attr('data-poll-chat-id');
        const optionId = $option.attr('data-option-id');
        const $pollContainer = $option.closest('.poll-container');

        // Don't do anything if clicking the same option again
        if ($option.hasClass('voted')) {
            console.log('Already voted, ignoring click');
            return;
        }

        // Disable clicking while processing
        $pollContainer.addClass('poll-voting');

        // Submit vote
        const headers = { 'Authorization': `Bearer ${jwt}`, 'Content-Type': 'application/json' };
        $.ajax({
            url: `${POLLING_SERVER_URL}/api/polls/vote`,
            method: 'POST',
            headers: headers,
            data: JSON.stringify({
                chat_id: chatId, // Parent of poll_id
                option_id: optionId // my vote
            }),
            success: function(response) {
                renderPoll(response?.poll_data);
            },
            error: function(xhr, status, err) {
                console.error(xhr, status, err);
                const error = xhr.responseJSON?.error || 'Failed to vote';
                alert(error);
            },
            complete: function() {
                $pollContainer.removeClass('poll-voting');
            }
        });
    });

    // Hover effect hints for active polls
    $(document).on('mouseenter', '.poll-active .poll-option.clickable', function() {
        const $status = $(this).closest('.poll-container').find('.poll-status');
        const originalText = $status.text();
        $status.data('original-text', originalText);
        $status.html('• <strong>Click to vote!</strong>');
    }).on('mouseleave', '.poll-active .poll-option.clickable', function() {
        const $status = $(this).closest('.poll-container').find('.poll-status');
        const originalText = $status.data('original-text');
        if (originalText) {
            $status.text(originalText);
        }
    });
});
